/*
游戏复杂player结构，代码结构模板，参考用

*/
#include "game_util/event_mgr.h"
#include "unit_test.h"
#include "misc.h"
#include <iostream>
#include <map>
#include <string>
#include "stl_boost.h"
#include "static_reg.h"
#include "singleton.h"
#include "../src/log_def.h"




using namespace std;
using namespace su;

namespace su
{
	template<>
	struct EventMgrTrait<11> {
		using Fun = void();
	};
	template<>
	struct EventMgrTrait<22> {
		using Fun = void(int a, int b);
	};
}

//关联db结构
namespace
{
	struct DbActor
	{
	};
	struct DbCom1
	{
		vector<int> vec;
	};
	struct DbPlayer // :public BaseTable
	{
		uint64_t uin = 0;
		std::string name;
		DbActor actor;
		DbCom1 com1;
		std::string myblob;
	};

}

namespace
{
	class Player;

	//Player组件例子
	//EventCom 选用，用了能侦听Player事件
	class PlayerCom1 : public EventCom
	{
		Player& m_owner;
		DbCom1& m_d; //引用 m_owner.m_DbPlayer.com1 
	public:
		PlayerCom1(Player& player);

		void OnNewPlayer();
	};
	//管理db操作
	class DbCom
	{
	public:
		Player& m_owner;

	public:
		DbCom(Player& player);
		void OnNewPlayer(); //查库失败，内存创建Player后 调用
		void Load(const DbPlayer &dbplayer);
		void Save();
	};

	class ActorOwner : public EventMgr, public Noncopyable
	{
	public:

	public:
		ActorOwner();
		virtual ~ActorOwner() {};
	};

	class TestActor : public EventCom
	{
	public:
		ActorOwner& m_owner;

	public:
		TestActor(ActorOwner& owner);
	};


	//只定义成员组件，尽量别写函数实现。相当于一个文件夹
	class Player : public ActorOwner, public EnableWeakPtr<Player>
	{
	public:
		DbPlayer   m_DbPlayer; //必须放前面，才能保证子组件引用不野
		DbCom      m_DbCom;
		PlayerCom1 m_PlayerCom1;
		TestActor	   m_actor;

		uint64 Uin() { return m_DbPlayer.uin; }
	};

	class Monster : public ActorOwner, public EnableWeakPtr<Player>
	{
	public:
		TestActor	   m_actor;

	private:

	};
	class Npc : public ActorOwner, public EnableWeakPtr<Player>
	{
	public:
		TestActor	   m_actor;

	private:

	};

	//implement
	/////////////////////////////////////////////
	PlayerCom1::PlayerCom1(Player& player)
		:EventCom(player)
		, m_owner(player)
		, m_d(player.m_DbPlayer.com1)
	{
	//	Reg<11>(&PlayerCom1::OnNewPlayer); reg OnNewPlayer
	}

	void PlayerCom1::OnNewPlayer()
	{
		//init m_d
		m_d.vec.clear();
	}

	DbCom::DbCom(Player& player)
		:m_owner(player)
	{

	}

	void DbCom::OnNewPlayer()
	{
		//m_owner.FireEvent<11>(); 
		//发送数据到DB插入。 只插入完整player数据
	}

	void DbCom::Load(const DbPlayer& dbplayer)
	{
		m_owner.m_DbPlayer = dbplayer;
	}

	void DbCom::Save()
	{
		//send m_DbPlayer to db 
	}

	TestActor::TestActor(ActorOwner& owner)
		:EventCom(owner)
		, m_owner(owner)
	{

	}
}

UNITTEST(test_gameStruct)
{
	//Player pp;
}